package file

import (
	"encoding/base64"
	"encoding/hex"
	"gitee.com/injoyai/goutil/conv"
	"io"
	"io/fs"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

const (
	defaultPerm = 0777
	ErrNotFind  = "The system cannot find the file specified"
)

// Read 读取文件
func Read(filename string) ([]byte, error) {
	return ReadBytes(filename)
}

// ReadBytes 读取文件内容
func ReadBytes(filename string) ([]byte, error) {
	return ioutil.ReadFile(filename)
}

// ReadString 读取文件
func ReadString(filename string) (string, error) {
	bs, err := ReadBytes(filename)
	return string(bs), err
}

// ReadHEX 读取文件
func ReadHEX(filename string) (string, error) {
	bs, err := ReadBytes(filename)
	return hex.EncodeToString(bs), err
}

// ReadBase64 读取文件
func ReadBase64(filename string) (string, error) {
	bs, err := ReadBytes(filename)
	return base64.StdEncoding.EncodeToString(bs), err
}

// NewFolder 新建文件夹
// @path,路径
func NewFolder(path string) error {
	return os.MkdirAll(path, defaultPerm)
}

// NewDir 新建文件夹
// @path,路径
func NewDir(path string) error {
	return os.MkdirAll(path, defaultPerm)
}

// NewWriteCloser 新建文件写入
func NewWriteCloser(name string) (io.WriteCloser, error) {
	return os.Create(name)
}

// NewIO same NewReadWriteCloser 新建IO
func NewIO(filename string) (io.ReadWriteCloser, error) {
	return os.Create(filename)
}

// OpenIO 打开IO
func OpenIO(filename string) (io.ReadWriteCloser, error) {
	return os.Open(filename)
}

// Open 打开
func Open(name string) (*os.File, error) {
	return os.Open(name)
}

// OpenFile 打开文件
func OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) {
	return os.OpenFile(name, flag, perm)
}

// Rename 重命名,转移文件
func Rename(oldPath, newPath string) error {
	return os.Rename(oldPath, newPath)
}

// Remove 删除文件(夹),文件夹不为空会报错
func Remove(path string) error {
	if err := os.Remove(path); err != nil &&
		!strings.Contains(err.Error(), ErrNotFind) {
		return err
	}
	return nil
}

// RemoveAll 删除文件(夹),包括文件里面数据
func RemoveAll(path string) error {
	if err := os.RemoveAll(path); err != nil &&
		!strings.Contains(err.Error(), ErrNotFind) {
		return err
	}
	return nil
}

// Del 删除文件(夹),文件夹不为空会报错
func Del(path string) error {
	return Remove(path)
}

// DelAll 删除文件(夹),包括文件里面数据
func DelAll(path string) error {
	return RemoveAll(path)
}

// Create 创建文件
func Create(path string, v ...interface{}) error {
	return New(path, v...)
}

// Range 遍历目录
func Range(dir string) ([]fs.FileInfo, error) {
	return ioutil.ReadDir(dir)
}

// RangeFunc 遍历目录
func RangeFunc(dir string, fn func(info fs.FileInfo) error) error {
	fileInfos, err := ioutil.ReadDir(dir)
	if err != nil {
		return err
	}
	for _, info := range fileInfos {
		if err = fn(info); err != nil {
			return err
		}
	}
	return nil
}

// New 新建文件,会覆盖
func New(path string, v ...interface{}) error {
	dir := filepath.Dir(path)
	name := filepath.Base(path)
	if err := os.MkdirAll(dir, defaultPerm); err != nil {
		return err
	}
	if len(name) == 0 {
		return nil
	}
	f, err := os.Create(path)
	if err != nil {
		return err
	}
	defer f.Close()
	if len(v) == 0 {
		return nil
	}
	data := []byte(nil)
	for _, k := range v {
		data = append(data, conv.Bytes(k)...)
	}
	_, err = f.Write(data)
	return err
}
